/// @tags: getMaxFlow DivGraph
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

namespace BlueQuantum {

typedef pair<int, int> pii;

int const N = 1e5 + 5, INF = 0x3f3f3f3f;

int n, S, T;
int e_cnt = 1;
int p[N];
int heads[N * 2], cur[N * 2], dep[N * 2], vis[N * 2];
pii ans[N];
vector<int> G[N];
queue<int> q;

struct Edge {
  int v, nxt, f;
} e[N * 8];

inline void add(int u, int v, int f) {
  e[++e_cnt] = (Edge){v, heads[u], f}, heads[u] = e_cnt;
  e[++e_cnt] = (Edge){u, heads[v], 0}, heads[v] = e_cnt;
}

inline int bfs() {
  memcpy(cur, heads, sizeof(cur));
  memset(dep, 0, sizeof(dep));
  dep[S] = 1;
  q.push(S);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = heads[u]; i; i = e[i].nxt) {
      int v = e[i].v;
      if (dep[v] == 0 && e[i].f) {
        dep[v] = dep[u] + 1;
        q.push(v);
      }
    }
  }
  return dep[T] != 0;
}

int dinic(int u, int flow) {
  if (u == T) return flow;
  int k, rest = flow;
  for (int &i = cur[u], v; i && rest; i = e[i].nxt) {
    if (dep[v = e[i].v] == dep[u] + 1 && e[i].f) {
      if ((k = dinic(v, min(rest, e[i].f)))) {
        e[i].f -= k;
        e[i ^ 1].f += k;
        rest -= k;
      }
    }
  }
  return flow - rest;
}

inline int getMaxFlow() {
  int res = 0;
  while (bfs()) res += dinic(S, INF);
  return res;
}

inline void solve() {
  for (int i = 2; i <= n; ++i) {
    for (int j = heads[i]; j; j = e[j].nxt) {
      int v = e[j].v;
      if (v != S && e[j].f == 0) {
        p[v - n] = i;
        break;
      }
    }
  }
  q.push(1);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int v : G[u]) {
      if (vis[v] == false) {
        ans[v] = make_pair(u, p[v]);
        q.push(p[v]);
        vis[v] = true;
      }
    }
  }
}

inline int main() {
  cin >> n;
  S = 1;
  for (int i = 2; i <= n; ++i) add(S, i, 1);
  for (int i = 1, c; i < n; ++i) {
    cin >> c;
    for (int j = 1, w; j <= c; ++j) {
      cin >> w;
      if (w != 1) add(w, i + n, 1);
      G[w].push_back(i);
    }
  }
  T = n + n;
  for (int i = 1; i < n; ++i) add(i + n, T, 1);
  if (getMaxFlow() < n - 1) {
    cout << "-1\n";
    return 0;
  }
  solve();
  for (int i = 1; i < n; ++i) cout << ans[i].first << ' ' << ans[i].second << '\n';
  return 0;
}

}  // namespace BlueQuantum

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("AT4505 [AGC029F] Construction of a tree.in", "r", stdin);
  freopen("AT4505 [AGC029F] Construction of a tree.out", "w", stdout);
#endif
#endif

  ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
  return BlueQuantum::main();
}
